package com.browseengine.bobo.facets.filter;

import java.io.IOException;

import org.apache.lucene.search.DocIdSetIterator;

import com.browseengine.bobo.api.BoboSegmentReader;
import com.browseengine.bobo.docidset.EmptyDocIdSet;
import com.browseengine.bobo.docidset.RandomAccessDocIdSet;
import com.browseengine.bobo.facets.data.MultiValueFacetDataCache;
import com.browseengine.bobo.facets.filter.FacetFilter.FacetDocIdSetIterator;
import com.browseengine.bobo.facets.range.MultiDataCacheBuilder;
import com.browseengine.bobo.util.BigNestedIntArray;

public class MultiValueFacetFilter extends RandomAccessFilter {
  private final String _val;

  private final MultiDataCacheBuilder multiDataCacheBuilder;

  public MultiValueFacetFilter(MultiDataCacheBuilder multiDataCacheBuilder, String val) {
    this.multiDataCacheBuilder = multiDataCacheBuilder;
    _val = val;
  }

  @Override
  public double getFacetSelectivity(BoboSegmentReader reader) {
    double selectivity = 0;
    MultiValueFacetDataCache<?> dataCache = multiDataCacheBuilder.build(reader);
    int idx = dataCache.valArray.indexOf(_val);
    if (idx < 0) {
      return 0.0;
    }
    int freq = dataCache.freqs[idx];
    int total = reader.maxDoc();
    selectivity = (double) freq / (double) total;
    return selectivity;
  }

  public final static class MultiValueFacetDocIdSetIterator extends FacetDocIdSetIterator {
    private final BigNestedIntArray _nestedArray;

    public MultiValueFacetDocIdSetIterator(MultiValueFacetDataCache<?> dataCache, int index) {
      super(dataCache, index);
      _nestedArray = dataCache._nestedArray;
    }

    @Override
    final public int nextDoc() throws IOException {
      return (_doc = (_doc < _maxID ? _nestedArray.findValue(_index, (_doc + 1), _maxID)
          : NO_MORE_DOCS));
    }

    @Override
    final public int advance(int id) throws IOException {
      if (_doc < id) {
        return (_doc = (id <= _maxID ? _nestedArray.findValue(_index, id, _maxID) : NO_MORE_DOCS));
      }
      return nextDoc();
    }
  }

  @Override
  public RandomAccessDocIdSet getRandomAccessDocIdSet(BoboSegmentReader reader) throws IOException {
    final MultiValueFacetDataCache<?> dataCache = multiDataCacheBuilder.build(reader);
    final int index = dataCache.valArray.indexOf(_val);
    final BigNestedIntArray nestedArray = dataCache._nestedArray;
    if (index < 0) {
      return EmptyDocIdSet.getInstance();
    } else {
      return new RandomAccessDocIdSet() {
        @Override
        public DocIdSetIterator iterator() {
          return new MultiValueFacetDocIdSetIterator(dataCache, index);
        }

        @Override
        final public boolean get(int docId) {
          return nestedArray.contains(docId, index);
        }

      };
    }
  }
}
